package com.bwie.bwedu.volley;

import android.content.Context;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
import com.bwie.bwedu.utils.LogUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * Created by chenxiangming on 15/8/13.
 */
public class MyJsonRequest<T> extends JsonRequest<T> {

	private Class<T> type;

	private static final String PROTOCOL_CONTENT_TYPE = "application/x-www-form-urlencoded";
	private static final String PROTOCOL_CHARSET = "utf-8";

	private static final String HEADER_ENCODING = "Content-Encoding";
	private static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
	private static final String ENCODING_GZIP = "gzip";
	private static final boolean mGzipEnabled = true;

	// 超时时间修改
	private static final int DEFAULT_TIME_OUT = 15000;

	private final String mRequestBody;

	private Map<String, String> headers = new HashMap<String, String>();

	private Context context;

	public MyJsonRequest(Context context, int method, String url,
			String params, Class<T> type, Response.Listener<T> listener,
			Response.ErrorListener errorListener) {

		super(method, url, params, listener, errorListener);
		this.type = type;
		mRequestBody = params;
		this.context = context;
		setRetryPolicy(new DefaultRetryPolicy(DEFAULT_TIME_OUT, 0, 0));
	}

	@Override
	public String getBodyContentType() {
		return PROTOCOL_CONTENT_TYPE;
	}

	@Override
	protected Response<T> parseNetworkResponse(NetworkResponse response) {
		try {
			String jsonString = getResponseString(response);


			ACache aCache =ACache.get(context);
			aCache.put("",jsonString);

			LogUtils.d("response--->" + jsonString);
			T t = null;
//
//
			t=GsonUtils.getInstance().jsonToObjeck(jsonString,
					type);
			return Response.success(t,
					HttpHeaderParser.parseCacheHeaders(response));
		} catch (Exception e) {
			return Response.error(new ParseError(e));
		}
	}

	private String getResponseString(NetworkResponse response)
			throws IOException {
		String responseString;
		String charset = HttpHeaderParser.parseCharset(response.headers);
		if (mGzipEnabled && isGzipped(response)) {
			byte[] data = decompressResponse(response.data);
			responseString = new String(data, charset);
		} else {
			responseString = new String(response.data, charset);
		}
		return responseString;
	}

	public Map<String, String> getHeaders() throws AuthFailureError {
		if (mGzipEnabled) {
			headers.put(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
		}
		return headers;
	}

	@Override
	public byte[] getBody() {
		try {
			return mRequestBody == null ? null : bodyAppendCurrentTime()
					.getBytes(PROTOCOL_CHARSET);
		} catch (UnsupportedEncodingException uee) {
			VolleyLog
					.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
							mRequestBody, PROTOCOL_CHARSET);
			return null;
		}
	}

	private String bodyAppendCurrentTime() {
		return mRequestBody + "&current_time=" + System.currentTimeMillis();
	}

	private boolean isGzipped(NetworkResponse response) {
		Map<String, String> headers = response.headers;
		return headers != null && !headers.isEmpty()
				&& headers.containsKey(HEADER_ENCODING)
				&& headers.get(HEADER_ENCODING).equalsIgnoreCase(ENCODING_GZIP);
	}

	protected byte[] decompressResponse(byte[] compressed) throws IOException {
		ByteArrayOutputStream baos = null;
		try {
			int size;
			ByteArrayInputStream memstream = new ByteArrayInputStream(
					compressed);
			GZIPInputStream gzip = new GZIPInputStream(memstream);
			final int buffSize = 8192;
			byte[] tempBuffer = new byte[buffSize];
			baos = new ByteArrayOutputStream();
			while ((size = gzip.read(tempBuffer, 0, buffSize)) != -1) {
				baos.write(tempBuffer, 0, size);
			}
			return baos.toByteArray();
		} finally {
			if (baos != null) {
				baos.close();
			}
		}
	}

}
